package com.share.common.utils;

import au.com.bytecode.opencsv.CSVReader;
import com.share.common.annotation.excel.ExcCol;
import com.share.common.model.excel.ExcModel;
import com.share.common.model.excel.ExcMsg;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.*;


public class CsvUtil {

    /**
     * 导入
     *
     * @return
     */
    public static List<String[]> readCsv(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            return null;
        }
        //windows必须要设置编码否则会乱码
        CSVReader reader = new CSVReader(new InputStreamReader(inputStream, Charset.forName("gbk")));
        return reader.readAll();
    }

    /**
     * 导出
     *
     * @param file     csv文件(路径+文件名)，csv文件不存在会自动创建
     * @param dataList
     * @return
     */
    public static boolean exportCsv(File file, List<String> dataList) {
        boolean isSucess = false;
        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file);
            osw = new OutputStreamWriter(out);
            bw = new BufferedWriter(osw);
            if (dataList != null && !dataList.isEmpty()) {
                for (String data : dataList) {
                    bw.append(data).append("\r");
                }
            }
            isSucess = true;
        } catch (Exception e) {
            isSucess = false;
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                    bw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (osw != null) {
                try {
                    osw.close();
                    osw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return isSucess;
    }

    /**
     * 导入
     *
     * @param file
     * @return
     */
    public static List<String> importCsv(File file) {
        List<String> dataList = new ArrayList<String>();
        BufferedReader br = null;
        try {
            //设置编码格式
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GBK"));
            String line = "";
            while ((line = br.readLine()) != null) {
                dataList.add(line);
            }
        } catch (Exception e) {
        } finally {
            if (br != null) {
                try {
                    br.close();
                    br = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return dataList;
    }


    /**
     * key 是sort--从0 开始
     * excModel为对应的描述
     *
     * @auther sunyanqiang
     * @date 2019/8/30 18:43
     */
    private static Map<Integer, ExcModel> csvImpAnalyBean(Class tClass) {
        Map<Integer, ExcModel> map = new HashMap<>();
        Field[] fields = tClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            ExcCol annotation = field.getAnnotation(ExcCol.class);
            if (annotation != null) {
                int sort = annotation.sort();
                String colounName = annotation.name();
                String format = annotation.format();
                String methodName = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                Class<?> filedclass = field.getType();//得到属性的类型
                Boolean enBlank = annotation.enBlank();
                map.put(sort, new ExcModel(sort, methodName, colounName, filedclass, format, enBlank));
            }
        }
        return map;
    }

    public static <T> ExcMsg<T> importCsv(InputStream inputStream, Class<T> tClass) throws Exception {
        ExcMsg excMsg = new ExcMsg();
        excMsg.setAnalySuceess(false);
        Map<Integer, ExcModel> initBean = csvImpAnalyBean(tClass);
        List<String[]> reList = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
        String csvDate = new String(reader.readLine().getBytes("ISO-8859-1"), "GBK");
        T t = null;
        int columnSize = initBean.size();
        List<T> dataList = new LinkedList<>();
        while ((csvDate = reader.readLine()) != null) {
            csvDate = csvDate.trim();
            String[] strs = csvDate.split(",");
            t = tClass.newInstance();
            for (Map.Entry<Integer, ExcModel> entry : initBean.entrySet()) {
                Integer sort = entry.getKey();
                ExcModel excModel = entry.getValue();
                Class classType = excModel.getFiledClass();
                String tmp = strs[sort].trim();
                Object changeValue = tmp;
                Method declaredMethod = t.getClass().getMethod(excModel.getMethodName(), classType);
                if (classType == Long.class) {
                    changeValue = Long.parseLong(tmp);
                } else if (classType == Integer.class) {
                    changeValue = Integer.parseInt(tmp);
                } else if (classType == Double.class) {
                    changeValue = Double.parseDouble(tmp);
                } else if (classType == Float.class) {
                    changeValue = Float.parseFloat(tmp);
                }
                declaredMethod.invoke(t, changeValue);
            }
            dataList.add(t);
        }
        excMsg.setDataList(dataList);
        excMsg.setAnalySuceess(true);
        return excMsg;
    }

    public static List<Map<String, Object>> readFileByLineList(InputStream inputStream) {
        List<Map<String, Object>> list = new ArrayList<>();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
            String tempString = new String(reader.readLine().getBytes("ISO-8859-1"), "GBK");
            int line = 1;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                System.out.println("line " + line + ": " + tempString);
                tempString = tempString.trim();

                String[] strs = tempString.split(",");
                Map<String, Object> map = new HashMap<String, Object>();
                //解析Excel科学计数法
                BigDecimal orderId = new BigDecimal(strs[0]);
                map.put("orderId", Long.valueOf(orderId.toPlainString()));//订单号
                map.put("skuId", strs[1]);// 商品id
                map.put("skuName", strs[2]);// 商品名字
                map.put("payType", strs[4]);                               //支付类型
                map.put("orderStartTime", strs[5]);                       //订单开始时间
                map.put("orderTotalPrice", strs[7]);                       //订单金额
                map.put("orderSellerPrice", strs[8]);                      //结算金额
                map.put("orderPayment", strs[10]);                         //应付金额
                map.put("orderState", strs[11]);                           //订单状态
                map.put("fullname", strs[14]);                             //客户名称
                map.put("mobile", strs[16]);                               //联系电话
                map.put("telephone", strs[16]);
                map.put("fullAddress", strs[15]);                          //客户地址
                map.put("oRemark", strs[17]);                          //买家备注
                map.put("orderSource", strs[28]);                          //订单来源
                list.add(map);
                line++;
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
        return list;
    }
}